package com.seven.annotation;

import com.seven.commons.*;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

@Component
@Aspect
@Order(2)
public class SevenValidateComponent extends BaseComponent {

    private static final Logger LOGGER = LoggerFactory.getLogger(SevenValidateComponent.class);

    private static final String ANNOTATION = "execution(* com..*.*Controller.*(..))" +
            "||execution(* com..*.*Controller.*(..)) and @annotation(org.springframework.web.bind.annotation.RequestBody)" +
            "||execution(* com..*.*Controller.*(..)) and @annotation(org.springframework.web.bind.annotation.RequestParam)||" +
            "execution(* com..*.*Controller.*(..)) and @annotation(org.springframework.web.bind.annotation.PathVariable)";

    private static final String VALUE_RESULT_TEMPLATE = ", 当前值为[%s]";

    @Pointcut(ANNOTATION)
    public void validator() {
    }


    /**
     * 進行參數验证的切入点的实现
     *
     * @param joinPoint
     * @return
     */
    @Around("validator()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Object obj = null;

        final Object[] args = joinPoint.getArgs();
        //没有参数不需要校验操作
        if (args.length == 0) {
            try {
                return joinPoint.proceed(args);
            } catch (Throwable throwable) {
                throw new AnnotationException(AnnotationEnum.VALIDATE_EXECUTE_ERROR.getCode(), AnnotationEnum.VALIDATE_EXECUTE_ERROR.getMsg());
            }
        }
        //校验bean类型的参数
        MethodSignature method = (MethodSignature) joinPoint.getSignature();
        Annotation[][] annotations = method.getMethod().getParameterAnnotations();
        for (int i = 0, size = annotations.length; i < size; i++) {
            Annotation[] annotations2 = annotations[i];
            //遍历单个参数的注解
            for (Annotation annotation : annotations2) {
                if (annotation != null && annotation instanceof SevenValidate) {
                    Object[] params = joinPoint.getArgs();
                    Object param = params[i];
                    Class<?>[] group = ((SevenValidate) annotation).group();
                    final String validate = BeanValidatorUtils.validate(param,group);
                    if (StringUtils.isNotEmpty(validate)) {
                        throw new AnnotationException(AnnotationEnum.VALIDATE_EXECUTE_ERROR.getCode(), validate);
                    }
                } else if (annotation != null) {
                    Object target = joinPoint.getThis();
                    //普通的参数校验
                    Object[] params = joinPoint.getArgs();
                    //Class<?>[] group = ((SevenValidate) annotation).group();
                    Method method1 = ((MethodSignature) joinPoint.getSignature()).getMethod();
                    final String validate = SpringBeanValidatorUtils.validate(method1, params, target,null);
                    if (StringUtils.isNotEmpty(validate)) {
                        throw new AnnotationException(AnnotationEnum.VALIDATE_EXECUTE_ERROR.getCode(), validate);
                    }
                }
            }
        }
        try {
            obj = joinPoint.proceed(args);
        } catch (Throwable throwable) {
            throwException(throwable);

        }
        return obj;
    }
}
